package com.navinfo.tripanalysis.common.arithmetic.convert;

import com.navinfo.tripanalysis.common.arithmetic.common.EngineAggregatedData;
import com.navinfo.tripanalysis.common.arithmetic.common.InterRangeData;
import com.navinfo.tripanalysis.common.util.GsonUtils;
import com.navinfo.tripanalysis.common.util.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.Metadata;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 行程发动机汇总数据与Parquet格式的转换
 *
 * @author 刘俊
 */
public class EngineDataParquetConvert {
    /**
     * 创建Schema
     *
     * @return
     */
    public static StructType createSchema() {
        List<StructField> list = new ArrayList<>();
        /*--start_schema*/
        //基础数据，统计字段
        list.add(new StructField("vin", DataTypes.StringType, true, Metadata.empty()));
        list.add(new StructField("tid", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("emissionStandard", DataTypes.StringType, true, Metadata.empty()));
        list.add(new StructField("carCategory", DataTypes.StringType, true, Metadata.empty()));
        list.add(new StructField("engineType", DataTypes.StringType, true, Metadata.empty()));
        list.add(new StructField("carType", DataTypes.StringType, true, Metadata.empty()));
        list.add(new StructField("tripId", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("routeStartTime", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("routeEndTime", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("routeDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("lastGpsTime", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("existEngineDataMiss", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("existEngineDataAbnormal", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("engineDataMissTerms", DataTypes.StringType, true, Metadata.empty()));
        list.add(new StructField("engineDataAbnmTerms", DataTypes.StringType, true, Metadata.empty()));
        //缺项时长
        list.add(new StructField("speedMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("barometricPressureMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("outputTorqueMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("frictionTorqueMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("rotationMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("fuelConsumptionMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrUpNOxMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrDownNOxMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("reagentAllowanceMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("airInflowMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrInMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrOutMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("dropoutVoltageMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("coolantTemperatureMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("tankLevelMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("positioningStateMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("longitudeMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("latitudeMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("mileageMissDuration", DataTypes.IntegerType, true, Metadata.empty()));
        //异常项时长
        list.add(new StructField("speedAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("barometricPressureAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("outputTorqueAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("frictionTorqueAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("rotationAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("fuelConsumptionAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrUpNOxAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrDownNOxAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("reagentAllowanceAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("airInflowAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrInAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrOutAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("dropoutVoltageAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("coolantTemperatureAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("tankLevelAbnmDuration", DataTypes.IntegerType, true, Metadata.empty()));

        list.add(new StructField("engineDataPoints", DataTypes.IntegerType, true, Metadata.empty()));
        //缺项点数和
        list.add(new StructField("speedMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("barometricPressureMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("outputTorqueMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("frictionTorqueMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("rotationMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("fuelConsumptionMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrUpNOxMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrDownNOxMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("reagentAllowanceMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("airInflowMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrInMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrOutMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("dropoutVoltageMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("coolantTemperatureMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("tankLevelMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("positioningStateMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("longitudeMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("latitudeMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("mileageMissPoints", DataTypes.IntegerType, true, Metadata.empty()));
        //异常项点数和
        list.add(new StructField("speedAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("barometricPressureAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("outputTorqueAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("frictionTorqueAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("rotationAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("fuelConsumptionAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrUpNOxAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrDownNOxAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("reagentAllowanceAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("airInflowAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrInAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrOutAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("dropoutVoltageAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("coolantTemperatureAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("tankLevelAbnmPoints", DataTypes.IntegerType, true, Metadata.empty()));
        //指标值总和
        list.add(new StructField("speedTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("barometricPressureTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("outputTorqueTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("frictionTorqueTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("rotationTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("fuelConsumptionTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("scrUpNOxTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("scrDownNOxTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("reagentAllowanceTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("airInflowTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("scrInTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("scrOutTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("dropoutVoltageTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("coolantTemperatureTotal", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("tankLevelTotal", DataTypes.LongType, true, Metadata.empty()));
        //指标值最大值
        list.add(new StructField("speedMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("barometricPressureMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("outputTorqueMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("frictionTorqueMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("rotationMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("fuelConsumptionMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrUpNOxMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrDownNOxMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("reagentAllowanceMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("airInflowMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrInMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrOutMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("dropoutVoltageMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("coolantTemperatureMax", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("tankLevelMax", DataTypes.IntegerType, true, Metadata.empty()));
        //指标值最小值
        list.add(new StructField("speedMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("barometricPressureMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("outputTorqueMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("frictionTorqueMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("rotationMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("fuelConsumptionMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrUpNOxMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrDownNOxMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("reagentAllowanceMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("airInflowMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrInMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("scrOutMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("dropoutVoltageMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("coolantTemperatureMin", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("tankLevelMin", DataTypes.IntegerType, true, Metadata.empty()));
        //排放分析相关字段
        list.add(new StructField("tripMileage", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("tripNoxAvg", DataTypes.DoubleType, true, Metadata.empty()));
        list.add(new StructField("specificEmissionQualifiedRate", DataTypes.DoubleType, true, Metadata.empty()));
        list.add(new StructField("directEmissionQualifiedRate", DataTypes.DoubleType, true, Metadata.empty()));
        list.add(new StructField("calcStartTime", DataTypes.StringType, true, Metadata.empty()));
        list.add(new StructField("calcEndTime", DataTypes.StringType, true, Metadata.empty()));
        /*--end_schema*/

        return new StructType(list.toArray(new StructField[list.size()]));
    }

    /**
     * 创建一行数据
     *
     * @param m
     * @param schema
     * @return
     */
    public static Row createRow(EngineAggregatedData m, StructType schema) {
        List<Object> list = new ArrayList<>();
        /*--start_row*/
        list.add(m.getVin());
        list.add(m.getTid());
        list.add(m.getEmissionStandard());
        list.add(m.getCarCategory());
        list.add(m.getEngineType());
        list.add(m.getCarType());
        list.add(m.getTripId());
        list.add(m.getRouteStartTime());
        list.add(m.getRouteEndTime());
        list.add(m.getRouteDuration());
        list.add(m.getLastGpsTime());
        list.add(m.getExistEngineDataMiss());
        list.add(m.getExistEngineDataAbnormal());
        list.add(m.getEngineDataMissTerms());
        list.add(m.getEngineDataAbnmTerms());

        list.add(m.getSpeedMissDuration());
        list.add(m.getBarometricPressureMissDuration());
        list.add(m.getOutputTorqueMissDuration());
        list.add(m.getFrictionTorqueMissDuration());
        list.add(m.getRotationMissDuration());
        list.add(m.getFuelConsumptionMissDuration());
        list.add(m.getScrUpNOxMissDuration());
        list.add(m.getScrDownNOxMissDuration());
        list.add(m.getReagentAllowanceMissDuration());
        list.add(m.getAirInflowMissDuration());
        list.add(m.getScrInMissDuration());
        list.add(m.getScrOutMissDuration());
        list.add(m.getDropoutVoltageMissDuration());
        list.add(m.getCoolantTemperatureMissDuration());
        list.add(m.getTankLevelMissDuration());
        list.add(m.getPositioningStateMissDuration());
        list.add(m.getLongitudeMissDuration());
        list.add(m.getLatitudeMissDuration());
        list.add(m.getMileageMissDuration());

        list.add(m.getSpeedAbnmDuration());
        list.add(m.getBarometricPressureAbnmDuration());
        list.add(m.getOutputTorqueAbnmDuration());
        list.add(m.getFrictionTorqueAbnmDuration());
        list.add(m.getRotationAbnmDuration());
        list.add(m.getFuelConsumptionAbnmDuration());
        list.add(m.getScrUpNOxAbnmDuration());
        list.add(m.getScrDownNOxAbnmDuration());
        list.add(m.getReagentAllowanceAbnmDuration());
        list.add(m.getAirInflowAbnmDuration());
        list.add(m.getScrInAbnmDuration());
        list.add(m.getScrOutAbnmDuration());
        list.add(m.getDropoutVoltageAbnmDuration());
        list.add(m.getCoolantTemperatureAbnmDuration());
        list.add(m.getTankLevelAbnmDuration());

        list.add(m.getEngineDataPoints());

        list.add(m.getSpeedMissPoints());
        list.add(m.getBarometricPressureMissPoints());
        list.add(m.getOutputTorqueMissPoints());
        list.add(m.getFrictionTorqueMissPoints());
        list.add(m.getRotationMissPoints());
        list.add(m.getFuelConsumptionMissPoints());
        list.add(m.getScrUpNOxMissPoints());
        list.add(m.getScrDownNOxMissPoints());
        list.add(m.getReagentAllowanceMissPoints());
        list.add(m.getAirInflowMissPoints());
        list.add(m.getScrInMissPoints());
        list.add(m.getScrOutMissPoints());
        list.add(m.getDropoutVoltageMissPoints());
        list.add(m.getCoolantTemperatureMissPoints());
        list.add(m.getTankLevelMissPoints());
        list.add(m.getPositioningStateMissPoints());
        list.add(m.getLongitudeMissPoints());
        list.add(m.getLatitudeMissPoints());
        list.add(m.getMileageMissPoints());

        list.add(m.getSpeedAbnmPoints());
        list.add(m.getBarometricPressureAbnmPoints());
        list.add(m.getOutputTorqueAbnmPoints());
        list.add(m.getFrictionTorqueAbnmPoints());
        list.add(m.getRotationAbnmPoints());
        list.add(m.getFuelConsumptionAbnmPoints());
        list.add(m.getScrUpNOxAbnmPoints());
        list.add(m.getScrDownNOxAbnmPoints());
        list.add(m.getReagentAllowanceAbnmPoints());
        list.add(m.getAirInflowAbnmPoints());
        list.add(m.getScrInAbnmPoints());
        list.add(m.getScrOutAbnmPoints());
        list.add(m.getDropoutVoltageAbnmPoints());
        list.add(m.getCoolantTemperatureAbnmPoints());
        list.add(m.getTankLevelAbnmPoints());

        list.add(m.getSpeedTotal());
        list.add(m.getBarometricPressureTotal());
        list.add(m.getOutputTorqueTotal());
        list.add(m.getFrictionTorqueTotal());
        list.add(m.getRotationTotal());
        list.add(m.getFuelConsumptionTotal());
        list.add(m.getScrUpNOxTotal());
        list.add(m.getScrDownNOxTotal());
        list.add(m.getReagentAllowanceTotal());
        list.add(m.getAirInflowTotal());
        list.add(m.getScrInTotal());
        list.add(m.getScrOutTotal());
        list.add(m.getDropoutVoltageTotal());
        list.add(m.getCoolantTemperatureTotal());
        list.add(m.getTankLevelTotal());

        list.add(m.getSpeedMax());
        list.add(m.getBarometricPressureMax());
        list.add(m.getOutputTorqueMax());
        list.add(m.getFrictionTorqueMax());
        list.add(m.getRotationMax());
        list.add(m.getFuelConsumptionMax());
        list.add(m.getScrUpNOxMax());
        list.add(m.getScrDownNOxMax());
        list.add(m.getReagentAllowanceMax());
        list.add(m.getAirInflowMax());
        list.add(m.getScrInMax());
        list.add(m.getScrOutMax());
        list.add(m.getDropoutVoltageMax());
        list.add(m.getCoolantTemperatureMax());
        list.add(m.getTankLevelMax());

        list.add(m.getSpeedMin());
        list.add(m.getBarometricPressureMin());
        list.add(m.getOutputTorqueMin());
        list.add(m.getFrictionTorqueMin());
        list.add(m.getRotationMin());
        list.add(m.getFuelConsumptionMin());
        list.add(m.getScrUpNOxMin());
        list.add(m.getScrDownNOxMin());
        list.add(m.getReagentAllowanceMin());
        list.add(m.getAirInflowMin());
        list.add(m.getScrInMin());
        list.add(m.getScrOutMin());
        list.add(m.getDropoutVoltageMin());
        list.add(m.getCoolantTemperatureMin());
        list.add(m.getTankLevelMin());
        //排放数据相关
        list.add(m.getTripMileage());
        list.add(m.getTripNoxAvg());
        list.add(m.getSpecificEmissionQualifiedRate());
        list.add(m.getDirectEmissionQualifiedRate());
        list.add(m.getCalcStartTime());
        list.add(m.getCalcEndTime());
        /*--end_row*/

        return new GenericRowWithSchema(list.toArray(), schema);
    }

    public static String toJsonStr(Object m) {
        if (m == null) {
            return null;
        }

        try {
            if (m instanceof Enum) {
                Enum m1 = (Enum) m;
                return m1.name();
            }
            return JsonUtils.toJsonIgnoreNull(m);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }


    public static Long getLong(Row row, String key) {
        Object o = row.getAs(key);
        if (o != null) {
            return Long.valueOf(o.toString());
        }
        return null;
    }

    public static Integer getInteger(Row row, String key) {
        Object o = row.getAs(key);
        if (o != null) {
            return Integer.valueOf(o.toString());
        }
        return null;
    }
    public static Double getDouble(Row row, String key) {
        Object o = row.getAs(key);
        if (o != null) {
            return Double.valueOf(o.toString());
        }
        return null;
    }

    public static String getString(Row row, String key) {
        Object o = row.getAs(key);
        if (o != null) {
            return o.toString();
        }
        return null;
    }

    /**
     * Row转为Pojo对象
     * @param row
     * @return
     */
    public static EngineAggregatedData fromRow(Row row) {
        EngineAggregatedData m = new EngineAggregatedData();
        /*--start_deserialization*/
        m.setVin(getString(row,"vin"));
        m.setTid(getLong(row,"tid"));
        m.setEmissionStandard(getString(row,"emission_standard"));
        m.setCarCategory(getString(row,"car_category"));
        m.setEngineType(getString(row,"engine_type"));
        m.setCarType(getString(row,"car_type"));
        m.setTripId(getInteger(row,"trip_id"));
        m.setRouteStartTime(getLong(row,"route_start_time"));
        m.setRouteEndTime(getLong(row,"route_end_time"));
        m.setRouteDuration(getInteger(row,"route_duration"));
        m.setExistEngineDataMiss(getInteger(row,"exist_engine_data_miss"));
        m.setExistEngineDataAbnormal(getInteger(row,"exist_engine_data_abnormal"));
        m.setEngineDataMissTerms(getString(row,"engine_data_miss_terms"));
        m.setEngineDataAbnmTerms(getString(row,"engine_data_abnormal_terms"));

        m.setSpeedMissDuration(getInteger(row,"speed_miss_duration"));
        m.setBarometricPressureMissDuration(getInteger(row,"barometric_pressure_miss_duration"));
        m.setOutputTorqueMissDuration(getInteger(row,"output_torque_miss_duration"));
        m.setFrictionTorqueMissDuration(getInteger(row,"friction_torque_miss_duration"));
        m.setRotationMissDuration(getInteger(row,"rotation_miss_duration"));
        m.setFuelConsumptionMissDuration(getInteger(row,"fuel_consumption_miss_duration"));
        m.setScrUpNOxMissDuration(getInteger(row,"scr_up_nox_miss_duration"));
        m.setScrDownNOxMissDuration(getInteger(row,"scr_down_nox_miss_duration"));
        m.setReagentAllowanceMissDuration(getInteger(row,"reagent_allowance_miss_duration"));
        m.setAirInflowMissDuration(getInteger(row,"air_inflow_miss_duration"));
        m.setScrInMissDuration(getInteger(row,"scr_in_miss_duration"));
        m.setScrOutMissDuration(getInteger(row,"scr_out_miss_duration"));
        m.setDropoutVoltageMissDuration(getInteger(row,"dropout_voltage_miss_duration"));
        m.setCoolantTemperatureMissDuration(getInteger(row,"coolant_temperature_miss_duration"));
        m.setTankLevelMissDuration(getInteger(row,"tank_level_miss_duration"));
        m.setPositioningStateMissDuration(getInteger(row,"positioning_state_miss_duration"));
        m.setLongitudeMissDuration(getInteger(row,"longitude_miss_duration"));
        m.setLatitudeMissDuration(getInteger(row,"latitude_miss_duration"));
        m.setMileageMissDuration(getInteger(row,"mileage_miss_duration"));

        m.setSpeedAbnmDuration(getInteger(row,"speed_abnm_duration"));
        m.setBarometricPressureAbnmDuration(getInteger(row,"barometric_pressure_abnm_duration"));
        m.setOutputTorqueAbnmDuration(getInteger(row,"output_torque_abnm_duration"));
        m.setFrictionTorqueAbnmDuration(getInteger(row,"friction_torque_abnm_duration"));
        m.setRotationAbnmDuration(getInteger(row,"rotation_abnm_duration"));
        m.setFuelConsumptionAbnmDuration(getInteger(row,"fuel_consumption_abnm_duration"));
        m.setScrUpNOxAbnmDuration(getInteger(row,"scr_up_nox_abnm_duration"));
        m.setScrDownNOxAbnmDuration(getInteger(row,"scr_down_nox_abnm_duration"));
        m.setReagentAllowanceAbnmDuration(getInteger(row,"reagent_allowance_abnm_duration"));
        m.setAirInflowAbnmDuration(getInteger(row,"air_inflow_abnm_duration"));
        m.setScrInAbnmDuration(getInteger(row,"scr_in_abnm_duration"));
        m.setScrOutAbnmDuration(getInteger(row,"scr_out_abnm_duration"));
        m.setDropoutVoltageAbnmDuration(getInteger(row,"dropout_voltage_abnm_duration"));
        m.setCoolantTemperatureAbnmDuration(getInteger(row,"coolant_temperature_abnm_duration"));
        m.setTankLevelAbnmDuration(getInteger(row,"tank_level_abnm_duration"));

        m.setEngineDataPoints(getInteger(row,"engine_data_points"));
        m.setSpeedMissPoints(getInteger(row,"speed_miss_points"));
        m.setBarometricPressureMissPoints(getInteger(row,"barometric_pressure_miss_points"));
        m.setOutputTorqueMissPoints(getInteger(row,"output_torque_miss_points"));
        m.setFrictionTorqueMissPoints(getInteger(row,"friction_torque_miss_points"));
        m.setRotationMissPoints(getInteger(row,"rotation_miss_points"));
        m.setFuelConsumptionMissPoints(getInteger(row,"fuel_consumption_miss_points"));
        m.setScrUpNOxMissPoints(getInteger(row,"scr_up_nox_miss_points"));
        m.setScrDownNOxMissPoints(getInteger(row,"scr_down_nox_miss_points"));
        m.setReagentAllowanceMissPoints(getInteger(row,"reagent_allowance_miss_points"));
        m.setAirInflowMissPoints(getInteger(row,"air_inflow_miss_points"));
        m.setScrInMissPoints(getInteger(row,"scr_in_miss_points"));
        m.setScrOutMissPoints(getInteger(row,"scr_out_miss_points"));
        m.setDropoutVoltageMissPoints(getInteger(row,"dropout_voltage_miss_points"));
        m.setCoolantTemperatureMissPoints(getInteger(row,"coolant_temperature_miss_points"));
        m.setTankLevelMissPoints(getInteger(row,"tank_level_miss_points"));
        m.setPositioningStateMissPoints(getInteger(row,"positioning_state_miss_points"));
        m.setLongitudeMissPoints(getInteger(row,"longitude_miss_points"));
        m.setLatitudeMissPoints(getInteger(row,"latitude_miss_points"));
        m.setMileageMissPoints(getInteger(row,"mileage_miss_points"));

        m.setSpeedAbnmPoints(getInteger(row,"speed_abnm_points"));
        m.setBarometricPressureAbnmPoints(getInteger(row,"barometric_pressure_abnm_points"));
        m.setOutputTorqueAbnmPoints(getInteger(row,"output_torque_abnm_points"));
        m.setFrictionTorqueAbnmPoints(getInteger(row,"friction_torque_abnm_points"));
        m.setRotationAbnmPoints(getInteger(row,"rotation_abnm_points"));
        m.setFuelConsumptionAbnmPoints(getInteger(row,"fuel_consumption_abnm_points"));
        m.setScrUpNOxAbnmPoints(getInteger(row,"scr_up_nox_abnm_points"));
        m.setScrDownNOxAbnmPoints(getInteger(row,"scr_down_nox_abnm_points"));
        m.setReagentAllowanceAbnmPoints(getInteger(row,"reagent_allowance_abnm_points"));
        m.setAirInflowAbnmPoints(getInteger(row,"air_inflow_abnm_points"));
        m.setScrInAbnmPoints(getInteger(row,"scr_in_abnm_points"));
        m.setScrOutAbnmPoints(getInteger(row,"scr_out_abnm_points"));
        m.setDropoutVoltageAbnmPoints(getInteger(row,"dropout_voltage_abnm_points"));
        m.setCoolantTemperatureAbnmPoints(getInteger(row,"coolant_temperature_abnm_points"));
        m.setTankLevelAbnmPoints(getInteger(row,"tank_level_abnm_points"));

        m.setSpeedTotal(getLong(row,"speed_total"));
        m.setBarometricPressureTotal(getLong(row,"barometric_pressure_total"));
        m.setOutputTorqueTotal(getLong(row,"output_torque_total"));
        m.setFrictionTorqueTotal(getLong(row,"friction_torque_total"));
        m.setRotationTotal(getLong(row,"rotation_total"));
        m.setFuelConsumptionTotal(getLong(row,"fuel_consumption_total"));
        m.setScrUpNOxTotal(getLong(row,"scr_up_nox_total"));
        m.setScrDownNOxTotal(getLong(row,"scr_down_nox_total"));
        m.setReagentAllowanceTotal(getLong(row,"reagent_allowance_total"));
        m.setAirInflowTotal(getLong(row,"air_inflow_total"));
        m.setScrInTotal(getLong(row,"scr_in_total"));
        m.setScrOutTotal(getLong(row,"scr_out_total"));
        m.setDropoutVoltageTotal(getLong(row,"dropout_voltage_total"));
        m.setCoolantTemperatureTotal(getLong(row,"coolant_temperature_total"));
        m.setTankLevelTotal(getLong(row,"tank_level_total"));

        m.setSpeedMax(getInteger(row,"speed_max"));
        m.setBarometricPressureMax(getInteger(row,"barometric_pressure_max"));
        m.setOutputTorqueMax(getInteger(row,"output_torque_max"));
        m.setFrictionTorqueMax(getInteger(row,"friction_torque_max"));
        m.setRotationMax(getInteger(row,"rotation_max"));
        m.setFuelConsumptionMax(getInteger(row,"fuel_consumption_max"));
        m.setScrUpNOxMax(getInteger(row,"scr_up_nox_max"));
        m.setScrDownNOxMax(getInteger(row,"scr_down_nox_max"));
        m.setReagentAllowanceMax(getInteger(row,"reagent_allowance_max"));
        m.setAirInflowMax(getInteger(row,"air_inflow_max"));
        m.setScrInMax(getInteger(row,"scr_in_max"));
        m.setScrOutMax(getInteger(row,"scr_out_max"));
        m.setDropoutVoltageMax(getInteger(row,"dropout_voltage_max"));
        m.setCoolantTemperatureMax(getInteger(row,"coolant_temperature_max"));
        m.setTankLevelMax(getInteger(row,"tank_level_max"));

        m.setSpeedMin(getInteger(row,"speed_min"));
        m.setBarometricPressureMin(getInteger(row,"barometric_pressure_min"));
        m.setOutputTorqueMin(getInteger(row,"output_torque_min"));
        m.setFrictionTorqueMin(getInteger(row,"friction_torque_min"));
        m.setRotationMin(getInteger(row,"rotation_min"));
        m.setFuelConsumptionMin(getInteger(row,"fuel_consumption_min"));
        m.setScrUpNOxMin(getInteger(row,"scr_up_nox_min"));
        m.setScrDownNOxMin(getInteger(row,"scr_down_nox_min"));
        m.setReagentAllowanceMin(getInteger(row,"reagent_allowance_min"));
        m.setAirInflowMin(getInteger(row,"air_inflow_min"));
        m.setScrInMin(getInteger(row,"scr_in_min"));
        m.setScrOutMin(getInteger(row,"scr_out_min"));
        m.setDropoutVoltageMin(getInteger(row,"dropout_voltage_min"));
        m.setCoolantTemperatureMin(getInteger(row,"coolant_temperature_min"));
        m.setTankLevelMin(getInteger(row,"tank_level_min"));

        m.setTripMileage(getInteger(row,"trip_mileage"));
        m.setTripNoxAvg(getDouble(row,"trip_nox_avg"));
        m.setSpecificEmissionQualifiedRate(getDouble(row,"specific_emission_qualified_rate"));
        m.setDirectEmissionQualifiedRate(getDouble(row,"direct_emission_qualified_rate"));
        m.setCalcStartTime(getString(row,"calc_start_time"));
        m.setCalcEndTime(getString(row,"calc_end_time"));

        return m;
    }

    private static Map<Integer, InterRangeData> getRangeData(Row row, String colName) {
        String jsonStr = getString(row,colName);
        if (StringUtils.isNotEmpty(jsonStr)) {
            Map<String, InterRangeData> map0 = GsonUtils.gsonToMap(jsonStr);
            Map<Integer, InterRangeData> map = new LinkedHashMap<>();
            for ( Map.Entry<String, InterRangeData> entry:map0.entrySet()) {
                map.put(Integer.valueOf(entry.getKey()), entry.getValue());
            }
            return map;
        }
        return null;
    }

}
